<?

class autoloader
{
	protected static $map;

	public static function get_map()
	{
		if ( !self::$map )
		{
			$cache_path = PROJECT_PATH . '/data/cache/autoload';
			if ( !is_file($cache_path) || ( !self::$map = include $cache_path ) || !config::get('cache') )
			{
				self::compile();
			}
		}

		return self::$map;
	}

	public static function compile( $force = false )
	{
		$cache_path = PROJECT_PATH . '/data/cache/autoload';
		self::$map = array();
		self::gather_classes( dirname(__FILE__) . '/..' );
		if ( defined('PROJECT_PATH') ) self::gather_classes(PROJECT_PATH);
		if ( config::get('cache') && ($force || $_SERVER['REQUEST_URI']) )
			file_put_contents($cache_path, self::generate_map_cache());
	}

	public static function gather_classes( $dir )
	{
		$i = new RecursiveIteratorIterator(
				new RecursiveDirectoryIterator($dir),
				RecursiveIteratorIterator::SELF_FIRST
			);

		foreach ($i as $file)
		{
			if ( pathinfo($file, PATHINFO_EXTENSION) == 'php' )
			{
				$data = file_get_contents( $file );

				if ( preg_match_all('/class ([a-z_0-9]+)/i', $data, $m) )
				{
					foreach ( $m[1] as $class_name ) self::$map[$class_name] = (string)$file;
				}
			}
		}
	}

	public static function get_path($class)
	{
		$map = self::get_map();
		return $map[$class];
	}

	public static function generate_map_cache()
	{
		$src = '<? return array(';
		
		foreach ( self::$map as $class => $path )
			$src .= "'{$class}' => '{$path}',\n";

		return $src . ');';
	}
}

function __autoload($name)
{
	if ( !$path = autoloader::get_path($name) ) return false;
	require $path;
}